package com.lightboat.framework.config;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.lightboat.common.core.text.Convert;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Data
@Slf4j
@Configuration
@AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedissonConfiguration {

    @Resource
    private RedisProperties redisProperties;

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + redisProperties.getHost() + ":" +redisProperties.getPort())
                .setDatabase(redisProperties.getDatabase())
                .setTimeout(Convert.toInt(redisProperties.getTimeout().toMillis(), 10000))
                .setConnectTimeout(10000)  // 连接超时时间 10秒
                .setIdleConnectionTimeout(30000)  // 空闲连接超时时间 30秒
                .setConnectionPoolSize(redisProperties.getLettuce().getPool().getMaxActive())
                .setConnectionMinimumIdleSize(redisProperties.getLettuce().getPool().getMinIdle())
                // 增加连接池大小以解决连接不足问题
                .setSubscriptionConnectionPoolSize(50)
                .setRetryAttempts(3)
                .setRetryInterval(1500)
                .setPingConnectionInterval(30000)
                .setKeepAlive(true)
                .setTcpNoDelay(true);
        if(StrUtil.isNotBlank(redisProperties.getPassword())){
            config.useSingleServer().setPassword(redisProperties.getPassword());
        }
        log.warn("redis config: {}", JSON.toJSONString(config));
        log.info("Attempting to connect to Redis at {}:{} with database {}", redisProperties.getHost(), redisProperties.getPort(), redisProperties.getDatabase());
        try {
            RedissonClient client = Redisson.create(config);
            log.info("Redis connection established successfully");
            return client;
        } catch (Exception e) {
            log.error("Failed to connect to Redis: {}", e.getMessage(), e);
            throw new RuntimeException("Redis connection failed: " + e.getMessage(), e);
        }
    }
}